
package com.oahcfly.chgame.core.ui;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Filter;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.utils.Array;
import com.oahcfly.chgame.core.listener.CHProgressBarListener;
import com.oahcfly.chgame.core.mvc.CHActor;

/**
 * 
 * 半透明蒙版
 * 圆形OR矩形技能冷却效果：
 * 先采用Pixmap生成黑色纹理，然后绘制时使用半透明处理，达到蒙版的效果。
 * 
 * @author haocao
 *
 */
public class CHCircleMaskProgressBar extends CHActor {

	private FileHandle fileHandle;
	// 圆的半径
	private float radius;
	// 总时长
	private float duration;
	// 三角形数量
	private final int MAX = 100;

	public enum PType {
		/**圆形冷却**/
		CIRCLE, 
		/**矩形冷却**/
		RECANGLE
	}

	private Texture pngTexture;

	public CHCircleMaskProgressBar (String pngName, float duration, PType type) {
		fileHandle = Gdx.files.internal(pngName);
		pngTexture = new Texture(fileHandle);
		this.duration = duration;
		Pixmap.setFilter(Filter.NearestNeighbour);
		onProgress();

		if (type == PType.CIRCLE) {
			// 内切圆
			radius = Math.max(getWidth() / 2, getHeight() / 2);
		} else if (type == PType.RECANGLE) {
			// 外切圆
			radius = (float)Math.sqrt(Math.pow(getWidth() / 2, 2) + Math.pow(getHeight() / 2, 2));
		}
	}

	// 进度标识：范围【0~MAX】
	private int proIdx = 0;

	private Array<CirclePoint> pointsArray = new Array<CHCircleMaskProgressBar.CirclePoint>();

	/**
	 * 开始进度
	 */
	public void startProgress () {
		if (pointsArray.size == 0) {
			// 角度
			float singleDegree = 360f / MAX;
			// 计算所有的点
			pointsArray.add(new CirclePoint((int)(getWidth() / 2), (int)(getHeight() / 2 - radius)));
			for (int i = proIdx + 1; i <= MAX; i++) {
				int x = (int)(getWidth() / 2 + radius * MathUtils.sinDeg(i * singleDegree));
				int y = (int)(getWidth() / 2 - radius * MathUtils.sinDeg(90 - i * singleDegree));
				pointsArray.add(new CirclePoint(x, y));
			}
		}
		// 单步时长
		float singleDuration = duration / MAX;
		addAction(Actions.repeat(MAX + 1, Actions.delay(singleDuration, Actions.run(new Runnable() {

			@Override
			public void run () {
				// 进度
				onProgress();
				proIdx++;
				proIdx = proIdx > MAX ? MAX : proIdx;
			}
		}))));
	}

	/**
	 * 每间隔1走1次进度
	 */
	private void onProgress () {
		if (proIdx == 0 && progressBarListener != null) {
			progressBarListener.onStart();
		}

		boolean isEnd = proIdx == MAX;
		if (isEnd && progressBarListener != null) {
			progressBarListener.onFinish();
		}

		Pixmap pixmap = new Pixmap(pngTexture.getWidth(), pngTexture.getHeight(), Format.RGBA4444);

		if (isEnd) {
			// 结束
			resetProgress();
		}
		pixmap.setColor(Color.BLACK);

		for (int i = proIdx, size = pointsArray.size; i < size; i++) {
			CirclePoint curPoint = pointsArray.get(i);
			if (i < size - 1) {
				CirclePoint nextPoint = pointsArray.get(i + 1);
				// 圆心
				int x1 = pixmap.getWidth() / 2;
				int y1 = pixmap.getHeight() / 2;
				int x2 = curPoint.x;
				int y2 = curPoint.y;
				int x3 = nextPoint.x;
				int y3 = nextPoint.y;
				y2 = y2 < 0 ? 0 : y2;
				y3 = y3 < 0 ? 0 : y3;
				pixmap.fillTriangle(x1, y1, x2, y2, x3, y3);
			}
		}
		Texture bgTexture = new Texture(pixmap);
		pixmap.dispose();

		Color bColor = new Color(Color.BLACK);
		bColor.a = isEnd ? 0 : 0.6f;
		setColor(bColor);
		setBgTexture(bgTexture);
	}

	@Override
	public void draw (Batch batch, float parentAlpha) {
		if (pngTexture != null) {
			batch.draw(pngTexture, getX(), getY(), getOriginX(), getOriginY(), getWidth(), getHeight(), getScaleX(), getScaleY(),
				getRotation(), 0, 0, (int)getWidth(), (int)getHeight(), false, false);
		}
		super.draw(batch, parentAlpha);
	}

	/**
	 * 重置进度
	 */
	private void resetProgress () {
		clearActions();
		proIdx = 0;
		stoped = false;
	}

	/**
	 * 正在执行进度中
	 * @return
	 */
	public boolean isProgressing () {
		return proIdx > 2;
	}

	private boolean stoped;

	public void stopProgress () {
		if (isProgressing()) stoped = true;
	}

	public void resumeProgress () {
		stoped = false;
	}

	/**
	 * 暂停与否
	 * @return
	 */
	public boolean isStoped () {
		return stoped;
	}

	@Override
	public void act (float delta) {
		if (stoped) return;
		super.act(delta);
	}

	private CHProgressBarListener progressBarListener;

	public void setProgressBarListener (CHProgressBarListener progressBarListener) {
		this.progressBarListener = progressBarListener;
	}

	@Override
	public boolean remove () {
		if (getBgTexture() != null) {
			getBgTexture().dispose();
		}
		return super.remove();
	}

	public class CirclePoint {
		public int x, y;

		public CirclePoint (int cx, int cy) {
			x = cx;
			y = cy;
		}
	}

	@Override
	public void drawAfterBg (Batch batch) {
		// TODO Auto-generated method stub

	}
}
